/*Copyright (c) 2009 Michael Streif
 *
 *Permission is hereby granted, free of charge, to any person obtaining a copy
 *of this software and associated documentation files (the "Software"), to deal
 *in the Software without restriction, including without limitation the rights
 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *copies of the Software, and to permit persons to whom the Software is
 *furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in
 *all copies or substantial portions of the Software.
 *
 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *THE SOFTWARE.
 */

#include "printk.h"
#include "stdarg.h"
#include "console.h"

char buffer [80];

char* itoa(uint64 val, uint32 radix)
{
	char* lookup = "0123456789ABCDEF";
	char temp [80];
	int32 i = 0;


	if (val == 0)
	{
		buffer[0] = '0';
		buffer[1] = '\0';
	}
	else
	{
		while (val != 0)
		{
			uint64 current = val % radix;
			val = val / radix;

			temp[i] = lookup[current];
			i++;
		}

		i--;
		int32 j = 0;
		int32 total = i;

		for ( ; j <= total; j++, i--)
		{
			buffer[j] = temp[i];
		}

		buffer[j] = '\0';
	}

	return buffer;
}

void printk(char* str, ...)
{
	va_list args;
	va_start(args, str);

	char* numstring;

	while (*str != '\0')
	{
		if (*str == '%')
		{
			str++;

			switch (*str)
			{
				case 'd':
				{
					numstring = itoa(va_arg(args, uint64), 10);
					puts(numstring);
					str++;

					break;
				}

				case 'h':
				{
					numstring = itoa(va_arg(args, uint64), 16);

					putch('0');
					putch('x');
					puts(numstring);
					str++;

					break;
				}

				case 'b':
				{
					numstring = itoa(va_arg(args, uint64), 2);

					putch('0');
					putch('b');
					puts(numstring);
					str++;

					break;
				}

				default:
				{
					str--;
					putch(*str);

					break;
				}
			}
		}
		else
		{
			putch (*str);
			str++;
		}
	}

	va_end(args);
}
